package com.example.sunny.service

import android.content.Context
import android.util.Log
import androidx.lifecycle.liveData
import com.example.sunny.pojo.location.MyLocation
import com.example.sunny.service.dao.PlaceDao
import com.example.sunny.service.network.SunnyNetwork
import com.example.sunny.pojo.place.Place
import com.example.sunny.pojo.weather.RealTimeResponse
import com.example.sunny.pojo.weather.Weather
import com.example.sunny.service.dao.WeatherDao
import com.example.sunny.utils.NetUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import java.lang.Exception
import java.lang.RuntimeException
import kotlin.coroutines.CoroutineContext

object Repository{

    //Dispatchers.IO指定代码块在子线程中执行
    fun searchPlaces(query:String) = fire(Dispatchers.IO){
        val placeResponse = SunnyNetwork.searchPlaces(query)
        if (placeResponse.status=="ok"){
            val places = placeResponse.places
            //封装
            Result.success(places)
        }else{
            Result.failure(RuntimeException("response status is ${placeResponse.status}"))
        }
    }

    fun refreshWeather(lng:String,lat:String,context:Context) = fire(Dispatchers.IO) {

        coroutineScope {
            //如果没有网络连接，则从数据库读取
            if (!NetUtils.isNetWorkConnected(context)){
                Log.d("Repository","没有网络从数据库中读取")
                val daily = WeatherDao.getDaily()
                val skycon:String = daily.skycon[0].value
                val temperature:Float = daily.temperature[0].run {
                    (max+min)/2
                }
                val airQuality = RealTimeResponse.AirQuality(
                    RealTimeResponse.AQI(daily.airQuality.aqi[0].avg.chn))

                val realtime  = RealTimeResponse.Realtime(skycon,temperature,airQuality)
                val weather = Weather(realtime,daily)
                Result.success(weather)
            }else{
                Log.d("Repository","有网络从api获取")
                val deferredRealtime = async{
                    SunnyNetwork.getRealtimeWeather(lng,lat)
                }
                val deferredDaily = async {
                    SunnyNetwork.getDailyWeather(lng,lat)
                }
                val realTimeResponse = deferredRealtime.await()
                val dailyResponse = deferredDaily.await()
                Log.d("Repository-realTimeResponse",realTimeResponse.toString())
                Log.d("Repository-dailyResponse",dailyResponse.toString())
                if (realTimeResponse.status=="ok" && dailyResponse.status=="ok"){
                    val weather = Weather(realTimeResponse.result.realtime,dailyResponse.result.daily)
                    Result.success(weather)
                }else{
                    Result.failure(
                        RuntimeException(
                            "realtime response status is ${realTimeResponse.status}"+
                                    "daily response status is ${dailyResponse.status}"
                        )
                    )
                }
            }

        }

    }

    private fun <T> fire(context:CoroutineContext,block:suspend() ->Result<T>) =
        liveData<Result<T>>(context) {
            val result = try{
                block()
            }catch (e:Exception){
                Result.failure<T>(e)
            }
            emit(result)
        }

    fun savePlace(place:Place) = PlaceDao.savePlace(place)

    fun getSavedPlaced() = PlaceDao.getSavedPlace()

    fun isPlaceSaved() = PlaceDao.isPlaceSaved()

    fun refreshLocation(): MyLocation?{
        Log.d("Repository","进入refreshLocation")

        val location = PlaceDao.getLocation()
        Log.d("RepositoryLocation",location.toString())
        return location
    }
}